/*******************************************************************************
 * @note Copyright (C) 2011-2022， Shanghai Panchip Microelectronics Co., Ltd. 
 * @SPDX-License-Identifier: Apache-2.0
 * @history - V0.1, 2022-09-28
*******************************************************************************/
#include "chirplan.h"
#include "pan3029_port.h"
#include "trng.h"
#include "hardware.h"
#include "aes_ecb.h"
#ifdef USBDONGLE
#include "hal_pwm.h"
#endif

/*
 * 信道选择，频率表
 * freq_table，频率表，需要上层提供初始值
 * freq_channel，信道表，本层使用，其值代表信道号，继承自freq_table，具体使用什么信道号需要网关入网回复帧提供
 * freq_channel的8个值依次为{up0，up1，up2，up_join，down0，down1，down2，down_join}，包含三组数据信道[up0,down0]，[up1,down1]，[up2,down2]和1组入网信道[up_join,down_join]
 * data_channel_num，数据信道数量，默认为SELECT_FREQ_TABLE_NUM/2-1，（需要减去一个入网信道）。其值会在网关入网回复帧中更新，data_channel_num取值范围为[1，SELECT_FREQ_TABLE_NUM/2-1]
*/
uint32_t freq_table[DEFAULT_FREQ_TABLE_NUM] = {0};
uint8_t  data_channel_num = (SELECT_FREQ_TABLE_NUM/2 - 1 );
uint8_t freq_channel[SELECT_FREQ_TABLE_NUM] = {1, 2, 3, 0, 9, 10, 11, 8};

chirplan_proc_t chirplan_proc;

extern uint8_t pan3029_irq_trigged_flag;

/*
 * mac状态机设置
 */
static void set_fsm_state(uint32_t state)
{
    chirplan_proc.fsm_state = state;
}

/*
 * mac状态机查询
 */
static uint8_t get_fsm_state(void)
{
    return chirplan_proc.fsm_state;
}

/*
 * RF发送状态保护
 * 防止在发送过程中，由于发射前的CAD TX检测，RF产生了rx中断，导致chirplan发送逻辑异常，因此需要对整个发送过程进行保护
 */
static void chirplan_set_mac_rfbusy_event_busy(void)
{
	chirplan_proc.rf_tx_busy_event = true;
	pan3029_irq_trigged_flag = false;
	
}

/*
 * RF发送状态查询
 */
static uint8_t chirplan_get_mac_rfbusy_event(void)
{
	return chirplan_proc.rf_tx_busy_event;
}

/*
 * 校验函数
 * buf为数组，len为数组长度
 */
static uint8_t chirplan_check_sum(uint8_t *buf, uint8_t len)
{ 
    uint8_t i, ret = 0;
 
    for(i=0; i<len; i++)
    {
        ret += *(buf++);
    }

    return ret;
}

/*
 * 通过此结构chirpmac_function向上层开放接口
 */
chirp_function_s chirpmac_function =
{
	chirplan_mac_init,
    chirplan_wakeup,
    chirplan_get_status,
    chirplan_get_send_status,
    chirplan_get_recv_status,
    chirplan_get_join_status,
    chirplan_rf_para_config,
	chirplan_rf_rate_config,
    chirplan_send,
    chirplan_join,
    chirplan_recv,
    chirplan_sleep,
    chirplan_reset,
    chirplan_classb_enter_rx,
    chirplan_irq_process,
};

/*初始状态*/
chirp_t *mac_chirp = NULL;
chirp_send_callback SendCallback = NULL;
chirp_recv_callback RecvCallback = NULL;
chirp_join_callback JoinCallback = NULL;
chirp_config_callback ConfigCallback = NULL;

/*
 * 获取ChirpLAN入网状态
 */
chirplan_join_status_t chirplan_get_join_status(void)
{
    return mac_chirp->all_status.join_status;
}

/*
 * 设置ChirpLAN入网状态
 */
static void chirplan_set_join_status(chirplan_join_status_t state)
{
	mac_chirp->all_status.join_status = state;
	show_mac_status();
}

/*
 * 获取ChirpLAN发送状态
 */
chirplan_send_status_t chirplan_get_send_status(void)
{
    return mac_chirp->all_status.send_status;
}

/*
 * 设置ChirpLAN发送状态
 */
static void chirplan_set_send_status(chirplan_send_status_t state)
{
	mac_chirp->all_status.send_status = state;
	show_mac_status();
}

/*
 * 获取ChirpLAN接收状态
 */
chirplan_recv_status_t chirplan_get_recv_status(void)
{
    return mac_chirp->all_status.recv_status;
}

/*
 * 设置ChirpLAN接收状态
 */
static void chirplan_set_recv_status(chirplan_recv_status_t state)
{
	mac_chirp->all_status.recv_status = state;
	show_mac_status();
}

/*
 * 获取ChirpLAN当前状态，空闲时可进入低功耗
 */
chirplan_state_t chirplan_get_status(void)
{
    return mac_chirp->all_status.mac_state;
}

/*
 * 设置ChirpLAN当前状态
 */
static void chirplan_set_state(chirplan_state_t state)
{
	mac_chirp->all_status.mac_state = state;
	show_mac_status();
}

/*
 * 获取ChirpLAN RF当前状态，传递RF事件
 */
static chirplan_rf_status_t chirplan_get_rf_state(void)
{
    return mac_chirp->all_status.rf_status;
}

/*
 * 设置ChirpLAN RF当前状态
 */
static void chirplan_set_rf_state(chirplan_rf_status_t state)
{
	mac_chirp->all_status.rf_status = state;
	show_mac_status();
}

/*
 * 接收窗口定时器超时事件
 */
void chirplan_rxtimeout_cb(void *ptr)
{
    chirp_debug("");
	stimer_stop(&chirplan_proc.stimer_chirplan_rxtimeout);

	chirplan_proc.rf_wait_rx_ack_event = false;	

	chirplan_set_rf_state(CHIRP_RF_RECV_ERR);
}

/*
 * 等待发送定时器超时事件
 */
void chirplan_txdelay_timeout_cb(void *ptr)
{
    chirp_debug("");
	stimer_stop(&chirplan_proc.stimer_chirplan_tx_delay_event);
	chirplan_proc.rf_wait_tx_timer_event = true;	
	chirplan_proc.cad_tx_join_flag = false;
}

void chirplan_cad_tx_timeout_cb(void *ptr)
{
    chirp_debug("");
	stimer_stop(&chirplan_proc.stimer_chirplan_cad_event);
	
	chirplan_proc.cad_tx_timeout_flag |= MAC_EVT_TX_CAD_TIMEOUT;
}

/*
 * mac层所有状态复位
 */
static void mac_status_reset(void)
{
	chirplan_proc.need_ack = false;
	chirplan_proc.cad_tx_try_times = 1;
	chirplan_proc.send_msg_try_times = 0;
	mac_chirp->app_data.RxLen = 0;
	mac_chirp->app_data.TxLen = 0;
	pan3029_irq_trigged_flag = false;
	chirplan_proc.rf_tx_busy_event = false;
	chirplan_set_join_status(CHIRP_RESET);
	set_fsm_state(FSM_STATE_IDLE);
	chirplan_set_state(CHIRP_STATE_IDLE);
	chirplan_set_send_status(CHIRP_SEND_IDLE);
	chirplan_set_recv_status(CHIRP_RECV_IDLE);
	chirplan_set_rf_state(CHIRP_RF_IDLE);
}


void chirplan_txsend_timeout_cb(void *ptr)
{
    chirp_debug("");
	stimer_stop(&chirplan_proc.stimer_chirplan_tx_send_event);

    if(rf_init() != OK)
    {
        chirplan_set_state(CHIRP_STATE_RF_ERR);
    }
	mac_status_reset();
	chirplan_set_send_status(CHIRP_SEND_ERR);
	if(SendCallback != NULL)
	{
		SendCallback();
	}	
}

/*
 * 设置发送信道，随机选择ch
 */
static chirplan_status_t mac_set_tx_ch(void)
{
	if(chirplan_proc.need_ack == false)/*发射数据，随机信道*/
	{
		mac_chirp->config.rf_config.ch = Trng_GetData0() % data_channel_num;		
	}

	mac_chirp->app_data.TxBuff[mac_chirp->app_data.TxLen - 2] = freq_channel[mac_chirp->config.rf_config.ch];
	mac_chirp->app_data.TxBuff[mac_chirp->app_data.TxLen - 1] = chirplan_check_sum(mac_chirp->app_data.TxBuff,mac_chirp->app_data.TxLen-2);
	
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
	printf("tx:%d",freq_table[freq_channel[mac_chirp->config.rf_config.ch]]);
#endif
	if(PAN3029_set_freq(freq_table[freq_channel[mac_chirp->config.rf_config.ch]]) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	return CHIRPLAN_STATUS_OK;
}

/*
 * 设置接收信道，根据发送信道选择对应的接收信道
 */
static chirplan_status_t mac_set_rx_ch(void)
{
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
	printf("rx:%d",freq_table[freq_channel[mac_chirp->config.rf_config.ch + (SELECT_FREQ_TABLE_NUM/2)]]);
#endif
	if(PAN3029_set_freq(freq_table[freq_channel[mac_chirp->config.rf_config.ch + (SELECT_FREQ_TABLE_NUM/2)]]) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	} 
	return CHIRPLAN_STATUS_OK;
}

/*
 * 选择Class C模式长接收信道，默认选取第一信道为长接收信道
 */
static chirplan_status_t mac_set_class_c_rx_ch(void)
{
	mac_chirp->config.rf_config.ch = 0;
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
	printf("C rx:%d",freq_table[freq_channel[mac_chirp->config.rf_config.ch + (SELECT_FREQ_TABLE_NUM/2)]]);
#endif
	if(PAN3029_set_freq(freq_table[freq_channel[mac_chirp->config.rf_config.ch + (SELECT_FREQ_TABLE_NUM/2)]]) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	} 
	return CHIRPLAN_STATUS_OK;
}

/*
 * 根据当前最新配置，设置RF参数
 */
static chirplan_status_t mac_set_para(void)
{
	if(PAN3029_set_mode(PAN3029_MODE_STB3) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_sf(mac_chirp->config.rf_config.sf) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_bw(mac_chirp->config.rf_config.bw) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_code_rate(mac_chirp->config.rf_config.cr) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_crc(mac_chirp->config.rf_config.crc) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_tx_power(mac_chirp->config.rf_config.tx_power) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_ldr(mac_chirp->config.rf_config.ldr) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_preamble_ms(mac_chirp->config.rf_config.preambletime) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	
	return CHIRPLAN_STATUS_OK;
}

/*
 * CAD检测函数，在RF初始化后，直接调用此接口，可检测当前信道状态
 * 用于接收前检测，信道忙时才可以接收
 * 返回值LEVEL_INACTIVE表示信道空闲
 * 返回值LEVEL_ACTIVE表示信道忙
 */
uint32_t check_cad_rx_inactive(uint32_t one_chirp_time)
{
	if(rf_set_cad(CAD_DETECT_THRESHOLD_20,CAD_DETECT_NUMBER_3) != OK)
	{
		chirp_debug("");
	}
	if(rf_enter_continous_rx() != OK)
	{
		chirp_debug("");
	}

    rf_delay_us(one_chirp_time*7);
    rf_delay_us(360);

    if(Gpio_GetInputIO(GPIO_PORT_CAD, GPIO_PIN_CAD) != 1)
    {
		if(PAN3029_set_mode(PAN3029_MODE_STB3) != OK)
		{
			chirp_debug("");
		}
		pan3029_irq_trigged_flag = false;
		PAN3029_clr_irq();
		return LEVEL_INACTIVE;
    }

	if(PAN3029_set_mode(PAN3029_MODE_STB3) != OK)
	{
		chirp_debug("");
	}
	pan3029_irq_trigged_flag = false;
	PAN3029_clr_irq();
    return LEVEL_ACTIVE;
}

/*
 * CAD检测函数，在RF初始化后，直接调用此接口，可检测当前信道状态
 * 用于发射前检测，信道空闲时才可以发射
 * chirplan_proc.cad_tx_timeout_flag为MAC_EVT_TX_CAD_TIMEOUT表示信道空闲
 * chirplan_proc.cad_tx_timeout_flag为MAC_EVT_TX_CAD_ACTIVE表示信道忙
 */
void check_cad_tx_inactive(void)
{
    if(rf_set_cad(CAD_DETECT_THRESHOLD_20, CAD_DETECT_NUMBER_3) != OK)
    {
		chirplan_set_state(CHIRP_STATE_RF_ERR);
		chirp_debug("");
	}
	
	chirplan_proc.cad_tx_timeout_flag = MAC_EVT_TX_CAD_NONE;
	
	if(rf_enter_continous_rx() != OK)
	{
		chirplan_set_state(CHIRP_STATE_RF_ERR);
		chirp_debug("");
	}
	
	stimer_set(&chirplan_proc.stimer_chirplan_cad_event,  \
			   chirplan_proc.one_chirp_time*3/1000 + 1,    \
			   STIMER_MODE_ONESHOT,        \
			   chirplan_cad_tx_timeout_cb, NULL);

}

/*
 * ChirpLAN初始化接口，根据传参初始化RF参数
 */
chirplan_status_t chirplan_mac_init(chirp_t *config, chirp_config_callback config_cb)
{
	if(config_cb != NULL)
	{
		chirp_debug("");
		ConfigCallback = config_cb;
	}
	mac_chirp = config;
    if(rf_init() != OK)
    {
        return CHIRPLAN_STATUS_RF_ERR;
    }
	mac_status_reset();
	return CHIRPLAN_STATUS_OK;
}
	
/*
 * ChirpLAN唤醒接口，休眠后可以直接唤醒
 */
chirplan_status_t chirplan_wakeup(void)
{
    if(rf_init() != OK)
    {
        return CHIRPLAN_STATUS_RF_ERR;
    }   
	
	/*对于B模式，唤醒后，配置相关参数，当上层检测到CAD后，可以直接进入接收，不需要再配置参数了*/
//	if((mac_chirp->config.workmode == CHIRP_CLASS_B)&&(chirplan_get_join_status() == CHIRP_SET))
//	{
//		if(mac_set_para() != CHIRPLAN_STATUS_OK)
//		{
//			return CHIRPLAN_STATUS_RF_ERR;
//		}
//		mac_chirp->config.rf_config.ch = 0;
//		mac_chirp->app_data.RxLen = 0;
//		if(mac_set_rx_ch() != CHIRPLAN_STATUS_OK)
//		{
//			return CHIRPLAN_STATUS_RF_ERR; 
//		} 
//	}
	if(mac_chirp->config.workmode == CHIRP_CLASS_C)
	{
		chirplan_set_recv_status(CHIRP_RECV_ING);
		chirplan_set_state(CHIRP_STATE_DOWNLINK);
		set_fsm_state(FSM_STATE_WAIT_IRQ);
		mac_set_class_c_rx_ch();
		rf_enter_continous_rx();
	}
    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN LOG显示
 */
static void show_mac_config( void )
{
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
	uint8_t i;
    printf("\r\n show_mac_config \r\n");
    printf("ch:%d\r\n",freq_channel[mac_chirp->config.rf_config.ch]);
	printf("sf:%d\r\n",mac_chirp->config.rf_config.sf);
    printf("bw:%d\r\n",mac_chirp->config.rf_config.bw);
    printf("cr:%d\r\n",mac_chirp->config.rf_config.cr);
    printf("crc:%d\r\n",mac_chirp->config.rf_config.crc);
	printf("tx_power:%d\r\n",mac_chirp->config.rf_config.tx_power);
    printf("ldr:%d\r\n",mac_chirp->config.rf_config.ldr);
	printf("upcnt:%d\r\n",mac_chirp->config.rf_config.upcnt);
    printf("preamble:%d\r\n",mac_chirp->config.rf_config.preambletime);
    printf("rxwindow:%d\r\n",mac_chirp->config.rf_config.rxwindow);
	printf("rxsleeptime:%d\r\n",mac_chirp->config.rf_config.rxsleeptime);
    printf("id:%x %08x %08x\r\n",mac_chirp->config.netid.app_id,mac_chirp->config.netid.gw_net_id,mac_chirp->config.netid.node_id);
	printf("mode0-2:%d\r\n",mac_chirp->config.workmode);
	printf("all_ch(%d):\r\n",data_channel_num);
		
	for(i = 0; i < SELECT_FREQ_TABLE_NUM; i++)
	{
		printf("%d ",freq_table[freq_channel[i]]);
	}
	printf("\r\n");
	
	for(i = 0; i < DEFAULT_FREQ_TABLE_NUM; i++)
	{
		printf("%d ",freq_table[i]);
	}
	printf("\r\n");
#endif
}

/*
 * ChirpLAN LOG显示
 */
void show_mac_status( void )
{
#ifdef _CHIRPLAN_DEBUG_LEVEL_HIGH_
	printf("\r\n show_mac_status \r\n");
	printf("send:%d\r\n",chirplan_get_send_status());
	printf("recv:%d\r\n",chirplan_get_recv_status());
	printf("mac:%d\r\n",chirplan_get_status());
	printf("join:%d\r\n",chirplan_get_join_status());
	printf("rf:%d\r\n",chirplan_get_rf_state());
	printf("\r\n");
#endif
}

/*
 * ChirpLAN 设置参数接口
 */
chirplan_status_t chirplan_rf_para_config( uint8_t txpower, uint8_t ldr, uint8_t crcOn, uint16_t preambletime, uint16_t rxwindow, uint16_t rxsleeptime)
{
	if(txpower > 29)
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	if(ldr > 1)
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	if(crcOn > 1)
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
    mac_chirp->config.rf_config.tx_power = txpower;
    mac_chirp->config.rf_config.ldr = ldr;
    mac_chirp->config.rf_config.crc = crcOn;
    mac_chirp->config.rf_config.preambletime = preambletime;
    mac_chirp->config.rf_config.rxwindow = rxwindow;
	mac_chirp->config.rf_config.rxsleeptime = rxsleeptime;
    
    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN 设置速率接口
 */
chirplan_status_t chirplan_rf_rate_config( uint8_t sf, uint8_t bandwidth, uint8_t coderate)
{
	if((bandwidth < 6) || (bandwidth > 9))
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	if((sf < 7) || (sf > 12))
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	if((coderate < 1) || (coderate > 4))
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	
    mac_chirp->config.rf_config.bw = bandwidth;
    mac_chirp->config.rf_config.cr = coderate;
    mac_chirp->config.rf_config.sf = sf;	

    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN 入网接口
 */
chirplan_status_t chirplan_join(chirp_join_callback join_cb)
{
	if(join_cb != NULL)
	{
		chirp_debug("");
		JoinCallback = join_cb;
	}
	chirplan_set_join_status(CHIRP_RESET);
	chirplan_set_send_status(CHIRP_SEND_ING);
    chirplan_set_state(CHIRP_STATE_UPLINK);
    mac_chirp->config.confirm = CHIRP_CONFIRMED_MSG;/*join is confirmed frame*/
	
	/*定义一个入网帧序号变量，只对入网帧序号进行计数*/
	static uint8_t joincnt = 0;

	mac_chirp->app_data.TxBuff[0] = MAC_FRAME_JOIN_REQ;
	mac_chirp->app_data.TxBuff[1] = joincnt;
	mac_chirp->app_data.TxBuff[2] = mac_chirp->config.netid.app_id;
    mac_chirp->app_data.TxBuff[3] = mac_chirp->config.netid.node_id >> 24;
    mac_chirp->app_data.TxBuff[4] = mac_chirp->config.netid.node_id >> 16;
    mac_chirp->app_data.TxBuff[5] = mac_chirp->config.netid.node_id >> 8;
    mac_chirp->app_data.TxBuff[6] = mac_chirp->config.netid.node_id;
	if(mac_chirp->config.workmode == CHIRP_CLASS_A)
	{
		mac_chirp->app_data.TxBuff[7] = MAC_FRAME_LP_TRX;
	}
//	else if(mac_chirp->config.workmode == CHIRP_CLASS_B)
//	{
//		mac_chirp->app_data.TxBuff[7] = MAC_FRAME_LP_RX;
//	}
	else if(mac_chirp->config.workmode == CHIRP_CLASS_C)
	{
		mac_chirp->app_data.TxBuff[7] = MAC_FRAME_RUN;
	}else{
		mac_chirp->app_data.TxBuff[7] = MAC_FRAME_RUN;
	}
    mac_chirp->app_data.TxBuff[8] = freq_channel[3];
//    mac_chirp->app_data.TxBuff[9] = Trng_GetData0();
//    mac_chirp->app_data.TxBuff[10] = Trng_GetData0();
//    mac_chirp->app_data.TxBuff[11] = Trng_GetData0();
//    mac_chirp->app_data.TxBuff[12] = Trng_GetData0();
	mac_chirp->app_data.TxBuff[9] = chirplan_check_sum(mac_chirp->app_data.TxBuff, MAC_FRAME_JOIN_REQ_LEN - 2);
    mac_chirp->app_data.TxLen = MAC_FRAME_JOIN_REQ_LEN;
	
    show_mac_config();
    
    PAN3029_set_mode(PAN3029_MODE_STB3);

	if(PAN3029_set_sf(mac_chirp->config.rf_config.sf) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_bw(mac_chirp->config.rf_config.bw) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_code_rate(mac_chirp->config.rf_config.cr) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_crc(mac_chirp->config.rf_config.crc) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_tx_power(mac_chirp->config.rf_config.tx_power) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	if(PAN3029_set_ldr(mac_chirp->config.rf_config.ldr) != OK)
	{
		return CHIRPLAN_STATUS_RF_ERR;
	}
	chirplan_proc.one_chirp_time = getOnepreamble(mac_chirp->config.rf_config.bw,mac_chirp->config.rf_config.sf);
	mac_chirp->config.rf_config.upcnt = 0;
	joincnt ++;
	chirplan_proc.send_msg_try_times = 0;
	chirplan_proc.cad_tx_join_time = 0;
	chirplan_proc.cad_tx_try_times = 1;
	chirplan_proc.rf_wait_tx_timer_event = true;	
	chirplan_proc.cad_tx_join_flag = true;
    set_fsm_state(FSM_STATE_CAD_TX_CHECK);

    return CHIRPLAN_STATUS_OK;
}
    
/*
 * ChirpLAN 数据发送接口，入网后生效，发送后需要等待send_cb返回才能继续发送
 */
chirplan_status_t chirplan_send(chirp_app_data_t * app_data, chirp_confirm_t confirmed, chirp_send_callback send_cb)
{

	if(send_cb != NULL)
	{
		chirp_debug("");
		SendCallback = send_cb;
	}else{
		SendCallback = NULL;
	}
    if(chirplan_get_join_status() == CHIRP_RESET)
    {
        return CHIRPLAN_STATUS_OTHER_ERR;
    }
    if(chirplan_get_send_status() == CHIRP_SEND_ING)
    {
        return CHIRPLAN_STATUS_OTHER_ERR;
    }
	if(app_data == NULL)
	{
		return CHIRPLAN_STATUS_OTHER_ERR;
	}
	/*对于加密数据，最大长度240字节，减去数据帧头部字段10字节，实际最大数据长度230字节*/
	/*对于非加密数据，最大长度255字节，减去数据帧头部字段10字节，实际最大数据长度245字节*/
	if(mac_chirp->config.crypt.enable == 1)
	{
		if(app_data->TxLen > 230)
		{
			return CHIRPLAN_STATUS_OTHER_ERR;
		}		
	}else{
		if(app_data->TxLen > 245)
		{
			return CHIRPLAN_STATUS_OTHER_ERR;
		}	
	}
	
	if(mac_chirp->config.workmode == CHIRP_CLASS_C)
	{
		/*C模式退出接收后，正常发送*/
		PAN3029_set_mode(PAN3029_MODE_STB3);
		mac_status_reset();
		chirplan_set_join_status(CHIRP_SET);
	}
		
	chirplan_set_send_status(CHIRP_SEND_ING);
	chirplan_set_state(CHIRP_STATE_UPLINK);
	mac_chirp->config.confirm = confirmed;    

	mac_chirp->config.rf_config.upcnt++;	
	
	if(mac_chirp->config.confirm == CHIRP_UNCONFIRMED_MSG)
	{
		mac_chirp->app_data.TxBuff[0] = MAC_FRAME_UNCONFIRM_UP;
	}else if(mac_chirp->config.confirm == CHIRP_CONFIRMED_MSG)
	{
		mac_chirp->app_data.TxBuff[0] = MAC_FRAME_CONFIRM_UP;
	}else
	{chirp_debug("");
		return CHIRPLAN_STATUS_OTHER_ERR;
	}

	mac_chirp->app_data.TxBuff[1] = mac_chirp->config.rf_config.upcnt;
	mac_chirp->app_data.TxBuff[2] = mac_chirp->config.netid.app_id;
	mac_chirp->app_data.TxBuff[3] = mac_chirp->config.netid.gw_net_id >> 24;
	mac_chirp->app_data.TxBuff[4] = mac_chirp->config.netid.gw_net_id >> 16;
	mac_chirp->app_data.TxBuff[5] = mac_chirp->config.netid.gw_net_id >> 8;
	mac_chirp->app_data.TxBuff[6] = mac_chirp->config.netid.gw_net_id;
	mac_chirp->app_data.TxBuff[7] = app_data->TxLen;
	memcpy(&mac_chirp->app_data.TxBuff[8], app_data->TxBuff, app_data->TxLen);

	mac_chirp->app_data.TxLen = app_data->TxLen + MAC_FRAME_UP_PACK_OFFSET;
	if(mac_set_para() != CHIRPLAN_STATUS_OK)
	{chirp_debug("");
		return CHIRPLAN_STATUS_RF_ERR;
	}
	chirplan_proc.one_chirp_time = getOnepreamble(mac_chirp->config.rf_config.bw,mac_chirp->config.rf_config.sf);//bw,sf

	show_mac_config();
	chirplan_proc.send_msg_try_times = 0;
	chirplan_proc.cad_tx_try_times = 1;
	chirplan_proc.rf_wait_tx_timer_event = true;	
	set_fsm_state(FSM_STATE_CAD_TX_CHECK);

	return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN 接收函数注册接口，注册后，当有接收到数据时，会调用recv_cb返回接收结果
 */
chirplan_status_t chirplan_recv(chirp_recv_callback recv_cb)
{
    if(recv_cb != NULL)
	{
		chirp_debug("");
		RecvCallback = recv_cb;
	}

    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN RF休眠接口，低功耗时使用，下次使用需要重新初始化或者唤醒
 */
chirplan_status_t chirplan_sleep(void)
{
    if(rf_deepsleep() != OK)
    {
        return CHIRPLAN_STATUS_RF_ERR;
    }   
    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN 重置mac层所有状态，下次使用需要重新初始化，并重新入网
 */
chirplan_status_t chirplan_reset(void)
{
    if(rf_deepsleep() != OK)
    {
        return CHIRPLAN_STATUS_RF_ERR;
    }   	
	mac_status_reset();
	
    return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN Class B接收接口
 */
chirplan_status_t chirplan_classb_enter_rx(void)
{
	/*参数在wakeup处配置过了*/
//	if((mac_chirp->config.workmode == CHIRP_CLASS_B)&&(chirplan_get_join_status() == CHIRP_SET))
//	{
//		chirplan_set_state(CHIRP_STATE_DOWNLINK);
//		chirplan_set_recv_status(CHIRP_RECV_ING);
//		chirplan_proc.one_chirp_time = getOnepreamble(mac_chirp->config.rf_config.bw,mac_chirp->config.rf_config.sf);//bw,sf
//		chirp_debug("%d",chirplan_proc.one_chirp_time*3/1000);
//		rf_enter_single_timeout_rx(chirplan_proc.one_chirp_time*3/1000);
//		set_fsm_state(FSM_STATE_WAIT_IRQ);
//		return CHIRPLAN_STATUS_OK;
//	}else{
		return CHIRPLAN_STATUS_OTHER_ERR;
//	}
}

/*
 * ChirpLAN RF中断处理函数
 */
void chirplan_irq_process( void )
{
    if( pan3029_irq_trigged_flag )
    {
		static uint8_t irq = 0;
		static uint8_t size;

        pan3029_irq_trigged_flag = false;
        irq = PAN3029_get_irq();
        
        chirp_debug("irq:%x",irq);
 
		if(chirplan_get_mac_rfbusy_event() == true)
		{
			if(irq & REG_IRQ_TX_DONE)
			{
				PAN3029_clr_irq();
				chirplan_set_rf_state(CHIRP_RF_SEND_OK);
				chirplan_proc.rf_tx_busy_event = false;
				stimer_stop(&chirplan_proc.stimer_chirplan_tx_send_event);
			}else{
				if(irq != PAN3029_get_irq())
				{
					PAN3029_clr_irq();
					chirplan_proc.rf_tx_busy_event = false;
					chirplan_set_rf_state(CHIRP_RF_RECV_ERR);  
				}else{
					PAN3029_clr_irq();
				}
			}
		}else{
		   if(irq & REG_IRQ_RX_DONE)
			{
				static uint8_t recv_buff[256];
				static uint8_t aes_encrypt[256]__attribute__ ((aligned (4))) = {0};
				size = PAN3029_recv_packet(recv_buff);
				chirp_debug("len:%d",size);
				if(recv_buff[0] & 0x80)
				{
					if((size-1)%16 == 0)
					{
						memcpy(aes_encrypt, &recv_buff[1], (size-1));
						decrypt(aes_encrypt, mac_chirp->app_data.RxBuff, mac_chirp->config.crypt.aes_key, 16, size-1);

						if(mac_chirp->app_data.RxBuff[0] == 0x82)
						{
							mac_chirp->app_data.RxLen = 25;
						}
						else if((mac_chirp->app_data.RxBuff[0] == 0x85)||(mac_chirp->app_data.RxBuff[0] == 0x86)||(mac_chirp->app_data.RxBuff[0] == 0x87))
						{
							mac_chirp->app_data.RxLen = mac_chirp->app_data.RxBuff[7] + 10;
							
						}else{
							mac_chirp->app_data.RxLen = 0;/*err*/
						}

					}else{
						mac_chirp->app_data.RxLen = 0;/*err*/
					}
				}else{
					mac_chirp->app_data.RxLen = size;
					memcpy(mac_chirp->app_data.RxBuff, recv_buff, size);
				}

				chirp_debug("%d",mac_chirp->app_data.RxLen);
				if(mac_chirp->app_data.RxLen != 0)
				{
					chirplan_set_rf_state(CHIRP_RF_RECV_OK);
				}else{
					chirplan_set_rf_state(CHIRP_RF_RECV_ERR);
				}
			}
			if(irq & REG_IRQ_CRC_ERR)
			{           
				PAN3029_clr_irq();
				chirplan_set_rf_state(CHIRP_RF_RECV_ERR);
			}
			if(irq & REG_IRQ_RX_TIMEOUT)
			{       
				PAN3029_clr_irq();
				chirplan_set_rf_state(CHIRP_RF_RECV_ERR);      
			}			
		}
    }
}

/*
 * ChirpLAN 入网帧校验函数
 */
static chirplan_status_t check_join_resp_pack( uint8_t *buff )
{
	uint8_t i;

	if(buff[2] != mac_chirp->config.netid.app_id)
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}

	if((buff[7] != (uint8_t)(mac_chirp->config.netid.node_id >> 24)) || (buff[8] != (uint8_t)(mac_chirp->config.netid.node_id >> 16)) || \
		(buff[9] != (uint8_t)(mac_chirp->config.netid.node_id >> 8)) || (buff[10] != (uint8_t)(mac_chirp->config.netid.node_id & 0xff)))
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
	
	if(chirplan_check_sum(buff,23) != buff[24])
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
	
	/*DEFAULT_FREQ_TABLE_NUM  buff:12...17*/
	for(i = 0; i < 6; i++)
	{
		if((buff[11+i] > DEFAULT_FREQ_TABLE_NUM))
		{chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}				
	}

	if(buff[17] != 0)/*bw*/
	{
		if((buff[17] < 6) || (buff[17] > 9))
		{chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
	}

	if(buff[18] != 0)/*sf*/
	{
		if((buff[18] < 7) || (buff[18] > 12))
		{chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
	}

	if(buff[19] != 0)/*ldr*/
	{
		if(((buff[19] >> 4) & 0x0F) > 1)
		{chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
	}
	
	if(buff[19] != 0)/*cr*/
	{
		if(((buff[19] & 0x0F) < 1) || ((buff[19] & 0x0F) > 4))
		{chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
	}
	
	if((buff[20] == 0)&&(buff[21] == 0))
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
		
	if(buff[22] > 3)/*0..3*/
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
		
	return CHIRPLAN_STATUS_OK;
}

/*
 * ChirpLAN 入网帧处理函数
 */
static void handle_join_resp_pack( uint8_t *buff )
{
	uint8_t i;
	mac_chirp->config.netid.gw_net_id = ((buff[3] << 24) | (buff[4] << 16) | (buff[5] << 8) | buff[6]);
	
	data_channel_num = 0;
	/*DEFAULT_FREQ_TABLE_NUM  buff:11...16*/
	for(i = 0; i < 3; i++)
	{
		if(buff[11+i] != 0)
		{
			data_channel_num ++;
		}
		/*freq_channel：0..2，buff：11..13*/
		freq_channel[i] = buff[11+i];
	}
	
	if(data_channel_num == 0)
	{
		data_channel_num = 1;/*buff[11] [12] [13] = 0*/
	}
	
	for(i = 4; i < 7; i++)
	{
		/*freq_channel：4..6，buff：14..16*/
		freq_channel[i] = buff[10+i];	
	}
	
	if(buff[17] != 0)
	{
		mac_chirp->config.rf_config.bw = buff[17];
	}
	
	if(buff[18] != 0)
	{
		mac_chirp->config.rf_config.sf = buff[18];
	}
	
	if(buff[19] != 0)
	{
		mac_chirp->config.rf_config.ldr = ((buff[19] >> 4) & 0x0F);
		mac_chirp->config.rf_config.cr = (buff[19] & 0x0F);
	}
	
	mac_chirp->config.rf_config.rxsleeptime = ((buff[20] << 8) | buff[21]);
	
	if(buff[22] == MAC_FRAME_LP_TRX)
	{
		mac_chirp->config.workmode = CHIRP_CLASS_A;
	}
//	else if(buff[22] == MAC_FRAME_LP_RX)
//	{
//		mac_chirp->config.workmode = CHIRP_CLASS_B;
//	}
	else if(buff[22] == MAC_FRAME_RUN)
	{
		mac_chirp->config.workmode = CHIRP_CLASS_C;
	}else{
		mac_chirp->config.workmode = CHIRP_CLASS_C;
	}
}
	
/*
 * ChirpLAN 数据帧ID校验函数
 */
static chirplan_status_t check_downlink_id( uint8_t *buff )
{
	if(chirplan_get_join_status() == CHIRP_RESET)
	{
		chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}

	if((buff[2] != mac_chirp->config.netid.app_id) || (buff[3] != (uint8_t)(mac_chirp->config.netid.gw_net_id >> 24)) || \
		(buff[4] != (uint8_t)(mac_chirp->config.netid.gw_net_id >> 16)) || (buff[5] != (uint8_t)(mac_chirp->config.netid.gw_net_id >> 8)) || (buff[6] != (uint8_t)(mac_chirp->config.netid.gw_net_id & 0xff)))
	{
		if((buff[2] == mac_chirp->config.netid.app_id) && (buff[3] == 0xff) && (buff[4] == 0xff) && (buff[5] == 0xff) && (buff[6] == 0xff))
		{
		}else{
			chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
	}
	
	if((mac_chirp->app_data.RxLen - 10) != buff[7])
	{
		chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
	
	if(chirplan_check_sum(buff,mac_chirp->app_data.RxLen-2) != buff[mac_chirp->app_data.RxLen-1])
	{chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
	
	return CHIRPLAN_STATUS_OK;
}
	
/*
 * ChirpLAN 数据帧解析函数
 */
static chirplan_status_t chirplan_mac_parse_data(void)
{
	uint8_t *buff,frame;
	
	buff = mac_chirp->app_data.RxBuff;
	print_hex(mac_chirp->app_data.RxBuff , mac_chirp->app_data.RxLen);

	frame = buff[0] & 0x7f;
	if(frame == MAC_FRAME_JOIN_RESP)
	{chirp_debug("");
		if(chirplan_get_join_status() == CHIRP_SET)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
		
		if(check_join_resp_pack(buff) != CHIRPLAN_STATUS_OK)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RECV_ERR;
		}
		
		handle_join_resp_pack(buff);
		
		show_mac_config();
		chirplan_set_recv_status(CHIRP_RECV_IDLE);
		chirplan_set_join_status(CHIRP_SET);
		#ifdef USBDONGLE
		PWM_Set_RGB(0);
		#endif
		chirplan_proc.one_chirp_time = getOnepreamble(mac_chirp->config.rf_config.bw,mac_chirp->config.rf_config.sf);//bw,sf
	
		if(mac_set_para() != CHIRPLAN_STATUS_OK)
		{
			return CHIRPLAN_STATUS_RF_ERR;
		}

		mac_chirp->config.rf_config.ch = 0;

		if(mac_set_rx_ch() != CHIRPLAN_STATUS_OK)
		{
			return CHIRPLAN_STATUS_RF_ERR; 
		} 

		mac_chirp->app_data.RxLen = 0;
		if(ConfigCallback != NULL)
		{
			ConfigCallback();
		}
		
		return CHIRPLAN_STATUS_OK;
		
	}
	else if(frame == MAC_FRAME_UNCONFIRM_DOWN)
	{chirp_debug("");
		if(check_downlink_id(buff) != CHIRPLAN_STATUS_OK)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RX_ID_ERR;
		}

		mac_chirp->app_data.RxLen = buff[7];
		if(mac_chirp->app_data.RxLen)
		{chirp_debug("");
			memcpy(mac_chirp->app_data.RxBuff, buff + 8, mac_chirp->app_data.RxLen);
			print_hex(mac_chirp->app_data.RxBuff , mac_chirp->app_data.RxLen);
			chirplan_set_recv_status(CHIRP_RECV_OK);
			
		}else
		{/*一个空包，是ACK包*/
			chirp_debug("ack");
		}
        return CHIRPLAN_STATUS_OK;                       
	}
	else if(frame == MAC_FRAME_CONFIRM_DOWN)
	{chirp_debug("");
		if(check_downlink_id(buff) != CHIRPLAN_STATUS_OK)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RX_ID_ERR;
		}
		
		mac_chirp->app_data.RxLen = buff[7];
		if(mac_chirp->app_data.RxLen)
		{
			memcpy(mac_chirp->app_data.RxBuff, buff + 8, mac_chirp->app_data.RxLen);
			print_hex(mac_chirp->app_data.RxBuff , mac_chirp->app_data.RxLen);
		}/*等发完ACK才通知用户*/
		
		/*ACK FRAME*/
		mac_chirp->app_data.TxBuff[0] = MAC_FRAME_UNCONFIRM_UP;
		mac_chirp->app_data.TxBuff[1] = buff[1];
		mac_chirp->app_data.TxBuff[2] = mac_chirp->config.netid.app_id;
		mac_chirp->app_data.TxBuff[3] = mac_chirp->config.netid.gw_net_id >> 24;
		mac_chirp->app_data.TxBuff[4] = mac_chirp->config.netid.gw_net_id >> 16;
		mac_chirp->app_data.TxBuff[5] = mac_chirp->config.netid.gw_net_id >> 8;
		mac_chirp->app_data.TxBuff[6] = mac_chirp->config.netid.gw_net_id;
		mac_chirp->app_data.TxBuff[7] = 0;
		mac_chirp->app_data.TxLen = MAC_FRAME_ACK_LEN;
		
		chirplan_proc.need_ack = true;

        return CHIRPLAN_STATUS_OK;   
	}
	else if(frame == MAC_FRAME_CONFIRM_CONFIG)/*未实现*/
	{chirp_debug("");
		if(check_downlink_id(buff) != CHIRPLAN_STATUS_OK)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RX_ID_ERR;
		}
		chirplan_set_recv_status(CHIRP_RECV_IDLE);
        return CHIRPLAN_STATUS_OK;    
	}
	else if(frame == MAC_FRAME_SYNC_RESP)/*同步应答*/
	{chirp_debug("");
		if(check_downlink_id(buff) != CHIRPLAN_STATUS_OK)
		{
			chirp_debug("");
			return CHIRPLAN_STATUS_RX_ID_ERR;
		}
		chirplan_set_recv_status(CHIRP_RECV_IDLE);
        return CHIRPLAN_STATUS_OK;    
	}
	else
	{
		chirp_debug("");
		return CHIRPLAN_STATUS_RECV_ERR;
	}
}

/*
 * ChirpLAN 设置发送信道函数
 */
static uint8_t chirplan_mac_process_set_channel( void )
{
   if(chirplan_get_join_status() == CHIRP_RESET)
	{/*入网*/
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
		printf("TX:%d",freq_table[freq_channel[(SELECT_FREQ_TABLE_NUM/2)-1]]);
#endif
		if(PAN3029_set_freq(freq_table[freq_channel[(SELECT_FREQ_TABLE_NUM/2)-1]]) != OK)
		{
			return FAIL;
		}    
	}
	else
	{
		if(mac_set_tx_ch() != CHIRPLAN_STATUS_OK)
		{
			return FAIL;
		} 					
	}
	return OK;
}

/*
 * ChirpLAN 发送数据函数，加密/不加密数据均可
 */
static uint8_t chirplan_mac_process_send_packet( void )
{
	if(rf_enter_continous_tx() != OK)
	{
		return FAIL;
	}

	static uint8_t txlen_encrypt;
	static uint8_t aes_txdata[256];
	if(mac_chirp->config.crypt.enable == 1)
	{
		aes_txdata[0] = mac_chirp->app_data.TxBuff[0] | 0x80;
		txlen_encrypt = app_aes_get_align_len(mac_chirp->app_data.TxLen);
		if(txlen_encrypt > 15*16)
		{
			return FAIL;
		}
		
		encrypt(mac_chirp->app_data.TxBuff, &aes_txdata[1], mac_chirp->config.crypt.aes_key, 16, txlen_encrypt);

		print_hex(mac_chirp->app_data.TxBuff , mac_chirp->app_data.TxLen);
		print_hex(aes_txdata , (txlen_encrypt + 1));
		chirplan_set_mac_rfbusy_event_busy();
		
		stimer_set(&chirplan_proc.stimer_chirplan_tx_send_event,  \
				   SEND_PACKET_MAX_TIME_MS,    \
				   STIMER_MODE_ONESHOT,        \
				   chirplan_txsend_timeout_cb, NULL);
		
		if (rf_continous_tx_send_data(aes_txdata , (txlen_encrypt + 1)) != Ok )
		{
			return FAIL;
		}		
		
	}else{
		print_hex(mac_chirp->app_data.TxBuff , mac_chirp->app_data.TxLen);
		chirplan_set_mac_rfbusy_event_busy();
		if (rf_continous_tx_send_data(mac_chirp->app_data.TxBuff , mac_chirp->app_data.TxLen) != Ok )
		{
			return FAIL;
		}	
	}
	return OK;
}

/*
 * ChirpLAN A模式接收错误处理函数
 */
static void handle_mode_A_rx_err_process( void )
{
	chirplan_proc.send_msg_try_times ++;
	if(chirplan_proc.send_msg_try_times < SEND_MSG_RETRY_TIME)
	{chirp_debug("");

		chirplan_set_recv_status(CHIRP_RECV_ERR);
		chirplan_set_state(CHIRP_STATE_UPLINK);
		chirplan_proc.rf_wait_tx_timer_event = true;	
		set_fsm_state(FSM_STATE_CAD_TX_CHECK);/*继续发射重传*/
	}else
	{
		chirplan_set_recv_status(CHIRP_RECV_IDLE);/*传输失败，重传也失败了*/
		chirplan_set_state(CHIRP_STATE_IDLE);
		set_fsm_state(FSM_STATE_IDLE);
		chirplan_set_send_status(CHIRP_SEND_ERR);
		if(SendCallback != NULL)
		{
			SendCallback();
		}
	}	
}

/*
 * ChirpLAN A模式接收正确处理函数
 */
static void handle_mode_A_rx_ok_process( void )
{
	if(chirplan_proc.need_ack == false)/*不需要ACK的下行*/
	{
		if(chirplan_proc.rf_wait_rx_ack_event == true)/*在等发送任务的ACK，完成该任务，A模式对任何收到的正确的包都认为是有效的ACK回复*/
		{
			stimer_stop(&chirplan_proc.stimer_chirplan_rxtimeout);
			chirplan_proc.rf_wait_rx_ack_event = false;
		}
		set_fsm_state(FSM_STATE_IDLE);
		chirplan_set_state(CHIRP_STATE_IDLE);/*发射结束，可以随时休眠了IDLE*/
		chirplan_set_send_status(CHIRP_SEND_OK);
		if(mac_chirp->config.workmode == CHIRP_CLASS_C)
		{
			chirplan_set_recv_status(CHIRP_RECV_ING);
			chirplan_set_state(CHIRP_STATE_DOWNLINK);
			set_fsm_state(FSM_STATE_WAIT_IRQ);
			mac_set_class_c_rx_ch();
			rf_enter_continous_rx();/*如果为A下入网，可能需要切换到C接收*/
		}
		if(SendCallback != NULL)
		{
			SendCallback();
		}
		if((RecvCallback != NULL)&&(mac_chirp->app_data.RxLen != 0))
		{
			RecvCallback();
		}
		
	}else{/*需要回复ACK*/
		chirplan_proc.send_msg_try_times = 0;
		chirplan_set_state(CHIRP_STATE_UPLINK);
		chirplan_proc.rf_wait_tx_timer_event = true;	
		set_fsm_state(FSM_STATE_CAD_TX_CHECK);/*回复ACK，ACK包在解析时已经组好了*/
	}
}

/*
 * ChirpLAN B模式接收错误处理函数
 */
static void handle_mode_B_rx_err_process( void )
{
	if(chirplan_get_send_status() == CHIRP_SEND_ING)
	{/*这是tx后的接收*/
		chirplan_proc.send_msg_try_times ++;
		if(chirplan_proc.send_msg_try_times < SEND_MSG_RETRY_TIME)
		{chirp_debug("");
			chirplan_set_recv_status(CHIRP_RECV_ERR);
			chirplan_set_state(CHIRP_STATE_UPLINK);
			chirplan_proc.rf_wait_tx_timer_event = true;	
			set_fsm_state(FSM_STATE_CAD_TX_CHECK);           
		}else
		{/*失败*/
				chirplan_set_recv_status(CHIRP_RECV_IDLE);
				chirplan_set_state(CHIRP_STATE_IDLE);
				set_fsm_state(FSM_STATE_IDLE);
				chirplan_set_send_status(CHIRP_SEND_ERR);
				if(SendCallback != NULL)
				{
					SendCallback();
				}
		}

	}else{/*轮询接收，RXERR，上报*/
			chirplan_set_recv_status(CHIRP_RECV_ERR);
			mac_chirp->app_data.RxLen = 0;
			chirplan_set_state(CHIRP_STATE_IDLE);
			set_fsm_state(FSM_STATE_IDLE);
			if(RecvCallback != NULL)
			{
				RecvCallback();
			}
	}
}

/*
 * ChirpLAN B模式接收正确处理函数
 */
static void handle_mode_B_rx_ok_process( void )
{
	if(chirplan_proc.need_ack == false)/*不需要ACK的下行*/
	{chirp_debug("");
		set_fsm_state(FSM_STATE_IDLE);
		chirplan_set_state(CHIRP_STATE_IDLE);

		if(chirplan_proc.rf_wait_rx_ack_event == true)/*在等发送任务的ACK，完成该任务*/
		{
			stimer_stop(&chirplan_proc.stimer_chirplan_rxtimeout);
			chirplan_proc.rf_wait_rx_ack_event = false;
			chirplan_set_send_status(CHIRP_SEND_OK);
			if(SendCallback != NULL)
			{
				SendCallback();
			}
		}
		if(mac_chirp->config.workmode == CHIRP_CLASS_C)/*如果为B下入网，可能需要切换到C接收*/
		{
			chirplan_set_recv_status(CHIRP_RECV_ING);
			chirplan_set_state(CHIRP_STATE_DOWNLINK);
			set_fsm_state(FSM_STATE_WAIT_IRQ);
			mac_set_class_c_rx_ch();
			rf_enter_continous_rx();
		}
		
		if((RecvCallback != NULL)&&(mac_chirp->app_data.RxLen != 0))
		{
			RecvCallback();
		}	
	}else{/*需要回复ACK*/
		chirplan_proc.send_msg_try_times = 0;
		chirplan_set_state(CHIRP_STATE_UPLINK);
		chirplan_proc.rf_wait_tx_timer_event = true;	
		set_fsm_state(FSM_STATE_CAD_TX_CHECK);/*回复ACK，ACK包在解析时已经组好了*/
	}
}

/*
 * ChirpLAN C模式接收错误处理函数
 */
static void handle_mode_C_rx_err_process( void )
{
	if(chirplan_get_send_status() == CHIRP_SEND_ING)
	{/*这是tx后的接收*/
		chirplan_proc.send_msg_try_times ++;
		if(chirplan_proc.send_msg_try_times < SEND_MSG_RETRY_TIME)
		{chirp_debug("");

			chirplan_set_recv_status(CHIRP_RECV_ERR);
			chirplan_set_state(CHIRP_STATE_UPLINK);
			chirplan_proc.rf_wait_tx_timer_event = true;	
			set_fsm_state(FSM_STATE_CAD_TX_CHECK);/*继续发射重传*/      
		}else
		{/*传输失败，重传也失败了*/
			if(chirplan_get_join_status() == CHIRP_SET)
			{
				chirplan_set_recv_status(CHIRP_RECV_ING);
				chirplan_set_state(CHIRP_STATE_DOWNLINK);
				set_fsm_state(FSM_STATE_WAIT_IRQ);
				chirplan_set_send_status(CHIRP_SEND_ERR);
				if(SendCallback != NULL)
				{
					SendCallback();
				}
				/*数据发送失败，回到默认频点接收*/
				mac_set_class_c_rx_ch();
				rf_enter_continous_rx();
			}else{/*入网失败*/
				chirplan_set_recv_status(CHIRP_RECV_IDLE);
				chirplan_set_state(CHIRP_STATE_IDLE);
				set_fsm_state(FSM_STATE_IDLE);
				chirplan_set_send_status(CHIRP_SEND_ERR);
				if(SendCallback != NULL)
				{
					SendCallback();
				}
			}
		}						
	}else{/*长接收的rxerr，不需要处理*/
				chirplan_set_recv_status(CHIRP_RECV_ING);
				chirplan_set_state(CHIRP_STATE_DOWNLINK);
				set_fsm_state(FSM_STATE_WAIT_IRQ);
				if(mac_chirp->config.rf_config.ch != 0)/*异常信道*/
				{chirp_debug("");
					mac_set_class_c_rx_ch();						
				}
				rf_enter_continous_rx();	
	}
}

/*
 * ChirpLAN C模式接收正确处理函数
 */
static void handle_mode_C_rx_ok_process( void )
{
	if(chirplan_proc.need_ack == false)/*不需要ACK的下行*/
	{
		if(chirplan_proc.rf_wait_rx_ack_event == true)/*在等发送任务的ACK，完成该任务，此处为入网成功*/
		{chirp_debug("");
			stimer_stop(&chirplan_proc.stimer_chirplan_rxtimeout);
			chirplan_proc.rf_wait_rx_ack_event = false;
			chirplan_set_send_status(CHIRP_SEND_OK);
			if(SendCallback != NULL)
			{chirp_debug("");
				SendCallback();
			}			
			if((RecvCallback != NULL)&&(mac_chirp->app_data.RxLen != 0))
			{chirp_debug("");
				RecvCallback();
			}
			mac_chirp->app_data.RxLen = 0;
		}
		
		set_fsm_state(FSM_STATE_IDLE);
		chirplan_set_state(CHIRP_STATE_IDLE);

		if(mac_chirp->config.workmode == CHIRP_CLASS_C)
		{
			chirplan_set_recv_status(CHIRP_RECV_ING);
			chirplan_set_state(CHIRP_STATE_DOWNLINK);
			set_fsm_state(FSM_STATE_WAIT_IRQ);
			mac_set_class_c_rx_ch();
			rf_enter_continous_rx();
		}
		if(mac_chirp->app_data.RxLen)/*有收到数据*/
		{chirp_debug("");
			if(RecvCallback != NULL)
			{
				RecvCallback();
			}
		}						
	}else{/*需要回复ACK*/
		chirplan_proc.send_msg_try_times = 0;
		chirplan_set_state(CHIRP_STATE_UPLINK);
		chirplan_proc.rf_wait_tx_timer_event = true;	
		set_fsm_state(FSM_STATE_CAD_TX_CHECK);
	}
}

/*
 * ChirpLAN mac层处理函数，应放在上层主循环中
 */
void chirplan_mac_process(void)
{
	static uint8_t chirp_status =  0;
    chirpmac_function.IrqProcess();

    switch (chirplan_proc.fsm_state)
    {
        case FSM_STATE_IDLE:
        
            break;
            
        case FSM_STATE_WAIT_IRQ:
            if(chirplan_get_rf_state() == CHIRP_RF_SEND_OK)
            {chirp_debug("");
                chirplan_set_rf_state(CHIRP_RF_IDLE);
				rf_set_mode( PAN3029_MODE_STB3 );
				rf_port.antenna_close();/*关闭PA*/
				if(chirplan_proc.need_ack == false)
				{
					if(mac_chirp->config.confirm == CHIRP_UNCONFIRMED_MSG)
					{
						if(mac_chirp->config.workmode == CHIRP_CLASS_C)
						{
							chirplan_set_recv_status(CHIRP_RECV_ING);
							chirplan_set_state(CHIRP_STATE_DOWNLINK);
							set_fsm_state(FSM_STATE_WAIT_IRQ);
							chirplan_set_send_status(CHIRP_SEND_OK);
							mac_set_class_c_rx_ch();/*C模式回到接收*/
							rf_enter_continous_rx();
							
						}else{/*A模式*/
							rf_set_mode( PAN3029_MODE_STB3 );
							set_fsm_state(FSM_STATE_IDLE);
							chirplan_set_state(CHIRP_STATE_IDLE);	
							chirplan_set_send_status(CHIRP_SEND_OK);
						}
						if(SendCallback != NULL)
						{
							SendCallback();
						}
						if((RecvCallback != NULL)&&(mac_chirp->app_data.RxLen != 0))
						{
							RecvCallback();
						}
					}else if(mac_chirp->config.confirm == CHIRP_CONFIRMED_MSG)
					{/*需要网关回复的发送，保持CHIRP_SEND_ING*/
						set_fsm_state(FSM_STATE_TX_HANDLE);
					}
				}else{/*发送ACK结束*/
					chirplan_proc.need_ack = false;
					if(mac_chirp->config.workmode == CHIRP_CLASS_C)
					{
						chirplan_set_recv_status(CHIRP_RECV_ING);
						chirplan_set_state(CHIRP_STATE_DOWNLINK);
						set_fsm_state(FSM_STATE_WAIT_IRQ);
						chirplan_set_send_status(CHIRP_SEND_OK);
						mac_set_class_c_rx_ch();
						rf_enter_continous_rx();
						
					}else{
						rf_set_mode( PAN3029_MODE_STB3 );
						set_fsm_state(FSM_STATE_IDLE);
						chirplan_set_state(CHIRP_STATE_IDLE);
						chirplan_set_send_status(CHIRP_SEND_OK);					
					}
					if(SendCallback != NULL)
					{
						SendCallback();
					}
					if((RecvCallback != NULL)&&(mac_chirp->app_data.RxLen != 0))
					{
						RecvCallback();
					}
				}	
            }

            if((chirplan_get_rf_state() == CHIRP_RF_RECV_OK) || ((chirplan_get_rf_state() == CHIRP_RF_RECV_ERR)))
            {chirp_debug("");
				if(chirplan_get_mac_rfbusy_event() == false)
				{
					rf_set_mode( PAN3029_MODE_STB3 );
					pan3029_irq_trigged_flag = false;
					PAN3029_clr_irq();
					set_fsm_state(FSM_STATE_RX_HANDLE);
				}else{
				}
            }           
            break;
        
        case FSM_STATE_CAD_TX_CHECK:
			
			if(chirplan_proc.rf_wait_tx_timer_event == true)
			{
				if(chirplan_mac_process_set_channel() != OK)
				{
					chirplan_set_state(CHIRP_STATE_RF_ERR);
				}
				
				/*入网帧先延时一段时间，再发起*/
				if((chirplan_proc.cad_tx_join_flag == true)&&(mac_chirp->app_data.TxBuff[0] == MAC_FRAME_JOIN_REQ))
				{
					chirplan_proc.cad_tx_join_time += 10;
					set_fsm_state(FSM_STATE_CAD_TX_DELAY); 
					break;					
				}else{			
					chirplan_proc.cad_tx_join_flag = true;
					check_cad_tx_inactive( );
					set_fsm_state(FSM_STATE_CAD_TX_SEND);
				}
			}
            break;
			
		case FSM_STATE_CAD_TX_SEND:
			
			if(chirplan_proc.cad_tx_timeout_flag & MAC_EVT_TX_CAD_ACTIVE)
			{
				chirplan_proc.cad_tx_timeout_flag &= ~ MAC_EVT_TX_CAD_ACTIVE;
				if(rf_set_mode(PAN3029_MODE_STB3) != OK)
				{
					chirp_debug("");
				}
				pan3029_irq_trigged_flag = false;
				rf_set_cad_off();
				
				if(chirplan_proc.cad_tx_try_times > SEND_MSG_CAD_RETRY_TIME)
				{chirp_debug("");/*发送失败*/
					chirplan_proc.cad_tx_try_times = 1;
					chirplan_proc.need_ack = false;
					chirplan_set_recv_status(CHIRP_RECV_IDLE);
					PAN3029_set_mode(PAN3029_MODE_STB3);
					chirplan_set_state(CHIRP_STATE_IDLE);
					set_fsm_state(FSM_STATE_IDLE);
					chirplan_set_send_status(CHIRP_SEND_ERR);
					if(SendCallback != NULL)
					{
						SendCallback();
					}
				}else
				{chirp_debug("");/*再次尝试*/
					chirplan_proc.cad_tx_try_times++;
					set_fsm_state(FSM_STATE_CAD_TX_DELAY);  
				}		
			}else if(chirplan_proc.cad_tx_timeout_flag & MAC_EVT_TX_CAD_TIMEOUT)
			{
				chirplan_proc.cad_tx_timeout_flag &= ~ MAC_EVT_TX_CAD_TIMEOUT;
				if(rf_set_mode(PAN3029_MODE_STB3) != OK)
				{
					chirplan_set_state(CHIRP_STATE_RF_ERR);
					chirp_debug("");
				}
				pan3029_irq_trigged_flag = false;
				rf_set_cad_off();
				chirplan_proc.cad_tx_try_times = 1;
				/*发送数据*/
				if(chirplan_mac_process_send_packet() != OK)
				{
					chirplan_set_state(CHIRP_STATE_RF_ERR);
				}
				set_fsm_state(FSM_STATE_WAIT_IRQ);		
			}
			
			break;
            
        case FSM_STATE_CAD_TX_DELAY:

			if(mac_chirp->app_data.TxBuff[0] != MAC_FRAME_JOIN_REQ)
			{
				chirplan_proc.cad_tx_join_time = 1;				
			}
			stimer_set(&chirplan_proc.stimer_chirplan_tx_delay_event,  \
					   chirplan_proc.cad_tx_join_time*chirplan_proc.cad_tx_try_times*(Trng_GetData0() % 100 + 1),    \
					   STIMER_MODE_ONESHOT,        \
					   chirplan_txdelay_timeout_cb, NULL);
			chirplan_proc.rf_wait_tx_timer_event = false;
			set_fsm_state(FSM_STATE_CAD_TX_CHECK);
            break;
            
        case FSM_STATE_TX_HANDLE:
            rf_set_mode( PAN3029_MODE_STB3 );
            if(chirplan_get_join_status() == CHIRP_RESET)
            {/*需要入网*/
#ifdef _CHIRPLAN_DEBUG_LEVEL_LOW_
				printf("JOINRX:%d",freq_table[freq_channel[SELECT_FREQ_TABLE_NUM-1]]);
#endif
                if(PAN3029_set_freq(freq_table[freq_channel[SELECT_FREQ_TABLE_NUM-1]]) != OK)
                {
                    chirplan_set_state(CHIRP_STATE_RF_ERR);
                }    
            }else
            {/*已入网，需要接收网关回复*/
				chirp_debug("%d",freq_table[freq_channel[mac_chirp->config.rf_config.ch + (SELECT_FREQ_TABLE_NUM/2)]]);
                if(mac_set_rx_ch() != CHIRPLAN_STATUS_OK)
                {
                    chirplan_set_state(CHIRP_STATE_RF_ERR);
                } 
            }           
            chirplan_set_state(CHIRP_STATE_DOWNLINK);
			chirplan_set_recv_status(CHIRP_RECV_ING);
			/*开启rxtimeout定时器*/
			stimer_set(&chirplan_proc.stimer_chirplan_rxtimeout,  \
					   mac_chirp->config.rf_config.rxwindow,    \
					   STIMER_MODE_ONESHOT,        \
					   chirplan_rxtimeout_cb, NULL);
			chirplan_proc.rf_wait_rx_ack_event = true;
			rf_enter_continous_rx();
            set_fsm_state(FSM_STATE_WAIT_IRQ);
            break;
        
        case FSM_STATE_RX_HANDLE:
			if(mac_chirp->config.workmode == CHIRP_CLASS_A)
			{
				if(chirplan_get_rf_state() == CHIRP_RF_RECV_ERR)
				{chirp_debug("");
					chirplan_set_rf_state(CHIRP_RF_IDLE);
					handle_mode_A_rx_err_process();
				}
				else if(chirplan_get_rf_state() == CHIRP_RF_RECV_OK)
				{chirp_debug("");
					chirplan_set_rf_state(CHIRP_RF_IDLE);
					
					chirp_status = chirplan_mac_parse_data();
					if(chirp_status == CHIRPLAN_STATUS_RX_ID_ERR)
					{
						rf_enter_continous_rx();
						set_fsm_state(FSM_STATE_WAIT_IRQ);
						/*继续接收*/
						
					}else if(chirp_status == CHIRPLAN_STATUS_OK)
					{
						handle_mode_A_rx_ok_process();
					}else/*其它解析错误*/
					{
						handle_mode_A_rx_err_process();
					}
				}
	   
//			}else if(mac_chirp->config.workmode == CHIRP_CLASS_B)
//			{
//				if(chirplan_get_rf_state() == CHIRP_RF_RECV_ERR)
//				{chirp_debug("");
//					chirplan_set_rf_state(CHIRP_RF_IDLE);
//					handle_mode_B_rx_err_process();

//				}else if(chirplan_get_rf_state() == CHIRP_RF_RECV_OK)
//				{chirp_debug("");
//					chirplan_set_rf_state(CHIRP_RF_IDLE);

//					chirp_status = chirplan_mac_parse_data();
//					if(chirp_status == CHIRPLAN_STATUS_OK)
//					{
//						handle_mode_B_rx_ok_process();
//					}else
//					{
//						handle_mode_B_rx_err_process();
//					}
//				}
			
			}else if(mac_chirp->config.workmode == CHIRP_CLASS_C)
			{
				if(chirplan_get_rf_state() == CHIRP_RF_RECV_ERR)
				{chirp_debug("");
					chirplan_set_rf_state(CHIRP_RF_IDLE);
					handle_mode_C_rx_err_process();
				
				}
				else if(chirplan_get_rf_state() == CHIRP_RF_RECV_OK)
				{chirp_debug("");
					chirplan_set_rf_state(CHIRP_RF_IDLE);

					chirp_status = chirplan_mac_parse_data();
					if(chirp_status == CHIRPLAN_STATUS_RX_ID_ERR)
					{
						rf_enter_continous_rx();
						set_fsm_state(FSM_STATE_WAIT_IRQ);
						/*继续接收*/
						
					}else if(chirp_status == CHIRPLAN_STATUS_OK)
					{
						handle_mode_C_rx_ok_process();
					}else
					{
						handle_mode_C_rx_err_process();
					}
				}      
			}
            break;

        default:
            break;
    }
}

